<?php

namespace App\Manage;


use App\Models\News;
use App\Models\NewsCate;
use App\Models\NewsDesc;
use App\Models\NewsTag;
use App\Models\SiteCate;
use App\Models\SiteInfo;
use App\Models\SiteTag;
use App\Models\User;
use App\Service\Base\Manage;
use App\Service\Translate;

class NewsManage extends Manage
{

    // 基本配置
    public function initialize()
    {
        parent::initialize();

        $this->model = 'News';
    }

    // 列表
    // 添加
    // 修改

    ## 查询统计
    public function getCount()
    {
        $opt     = $this->option();
        $rows    = $opt->getData('rows', 15, 'intval');
        $tag_id  = $opt->getData('tag_id', null, 'intval');
        $cate_id = $opt->getData('cate_id', null, 'intval');

        // 模型 和 查询
        $model = new News();
        $query = $model->from('news');
        if($tag_id){
            $query = $query->join('news_tag as tag', 'news.id', '=', 'tag.news_id');
        }
        if($cate_id){
            $query = $query->join('news_cate as cate', 'news.id', '=', 'cate.news_id');
        }

        $where = $this->listWhere();
        $nums  = $query->where($where)->count();
        if($nums === false){
            return $this->_returnFail($this->error);
        }

        return $nums;
    }

    // 列表
    protected function getLists()
    {
        $opt   = $this->option();
        $page  = $opt->getData('page', 1, 'intval');
        $rows  = $opt->getData('rows', 15, 'intval');
        $start = ($page - 1) * $rows;

        // 查询字段
        $cacheKey = 'lists';
        $tag_id   = $opt->getData('tag_id', null, 'intval');
        $cate_id  = $opt->getData('cate_id', null, 'intval');
        $fields   = ['news.*'];
        if($tag_id){
            $cacheKey = 'taglistspage';
            $fields[] = 'tag.news_id';
            $fields[] = 'tag.tag_id';
        }
        if($cate_id){
            $cacheKey = 'catelistspage';
            $fields[] = 'cate.news_id';
            $fields[] = 'cate.cate_id';
        }

        // 模型 和 查询
        $model = new News();
        $bang  = $this->bang;
        $where = $this->listWhere();

        // 缓存
        $args   = compact('where', 'page', 'rows');
        $KCache = $model->cacheKey($cacheKey, $args);
        $lists  = $model->cacheClass()->getCache($KCache);
        // 检查是否已经绑定
        if(!empty($lists)){
            $model->checkBangList($lists, $KCache);
        }

        // 查询
        if(empty($lists)){
            $query = $model->from('news');
            if($tag_id){
                $query = $query->join('news_tag as tag', 'news.id', '=', 'tag.news_id');
            }
            if($cate_id){
                $query = $query->join('news_cate as cate', 'news.id', '=', 'cate.news_id');
            }

            // 执行查询
            $query = $query->where($where)->select($fields)->forPage($page, $rows)->orderBy('news.id', 'DESC');
            //$count = $query->where($where)->count();
            // 查找过滤
            $lists = $query->get()->toArray();

            // 保存为缓存
            if($bang){
                $model->bangField($bang)->addCacheList($lists, $KCache, $lists, 'list');
            }
        }

        // 整理
        $lists = $this->makeNewsListsResult($lists);

        return $lists;
    }

    // 详情
    protected function toShow()
    {
        $where = $this->showWhere();
        if($where === false){
            return $this->_returnFail($this->error);
        }

        $model = $this->checkModel($this->model);
        $info  = $model->isCache(true)->oneFind($where);
        if($info === false){
            return $this->_returnFail($model->getError());
        }

        $info = is_object($info) ? $info->toArray() : $info;
        // 整理
        $info = $this->makeNewsInfoResult($info);

        return $info;
    }

    // 软删除
    protected function toSoft()
    {
        $opt  = $this->option();
        $_id  = $opt->getData('id', 0, 'intval');
        $_ids = $opt->getData('ids', [], 'is_array');
        if(empty($_id) && empty($_ids)){
            return $this->_returnFail('请指定删除记录');
        }

        // 删除
        $_ids  = $_ids ?: [$_id];
        $model = new News();
        foreach($_ids as $_id){
            $where  = ['id' => $_id];
            $result = $model->isCache(true)->softDelete($where);
            if($result === false){
                return $this->_returnFail($model->getError());
            }
        }

        return $result;
    }

    // 突发，头条，标红（重大）新闻
    public function onChangeNewsType($field)
    {
        $opt    = $this->option();
        $_value = $opt->getData('value', null, 'intval');
        $_id    = $opt->getData('id', 0, 'intval');
        $_ids   = $opt->getData('ids', [], 'is_array');
        if(is_null($_value)){
            return $this->_returnFail('状态必须填写！！');
        }
        if(empty($_id) && empty($_ids)){
            return $this->_returnFail('请指定操作记录！！');
        }

        // 突发，头条，标红 状态只能为 0,1
        if(in_array($field, ['is_top', 'is_header', 'is_major']) && (!in_array($_value, [0, 1]))){
            return $this->_returnFail('状态必须为0或1！！');
        }

        if($_value == 1){
            $data = [$field => $_value,];
            if($field == 'is_major'){
                $data['major_time'] = LARAVEL_TIME;
            } elseif($field == 'is_top'){
                $data['top_time'] = LARAVEL_TIME;
            } elseif($field == 'is_email'){
                $data['email_time'] = LARAVEL_TIME;
            }
        } else{
            $data = [$field => $_value,];
            if($field == 'is_major'){
                $data['major_time'] = 0;
            } elseif($field == 'is_top'){
                $data['top_time'] = 0;
            } elseif($field == 'is_email'){
                $data['email_time'] = 0;
            }
        }

        // 执行
        $_ids  = $_ids ?: [$_id];
        $model = new News();
        $lists = $model->isCache(true)->getListInIds($_ids);
        // 检查数据
        //  头条的时候必须有标题，有图片
        if($field == 'is_top'){
            foreach($lists as $_row){
                if(empty($_row['pic']) || empty($_row['en_title'])){
                    return $this->_returnFail('设置头条必须要有标题有图片！！');
                }
            }
        }

        // 执行
        foreach($_ids as $_id){
            $where  = ['id' => $_id];
            $result = $model->where($where)->update($data);
            if($result === false){
                return $this->_returnFail($model->getError());
            }
        }

        // 删除缓存
        foreach($lists as $key => $val){
            $lists[$key][$field] = $_value;
        }
        $model->deleteCacheList($lists);

        return $result;
    }

    // 添加
    public function onAdd()
    {
        $opt    = $this->option();
        $cates  = $opt->getData("cates", [], "is_array");
        $tags   = $opt->getData("tag_ids", [], "is_array");
        $cateId = $opt->getData("cate_id", 0, "intval");
        $_uid   = $opt->getData('uid', 86, 'intval'); // 默认
        $data   = $this->_before();
        if($data === false){
            return $this->_returnFail('add_the_saved_data');
        }
        if(empty($_uid)){
            return $this->_returnFail('select_the_posting_user');
        }
        if(empty($cateId)){
            //return $this->_returnFail('select_the_posting_cate');
        }

        // 整理标签
        $en_keywords = $data['en_keywords'] ?? [];
        $cn_keywords = $data['cn_keywords'] ?? [];
        if($en_keywords){
            $tags = $this->getTagsFromKeyWord($en_keywords, $cn_keywords);
            if($tags === false){
                return false;
            }
        }

        // 验证
        $cates  = [$cateId];
        $model  = new News();
        $result = $model->checkRules($data, 'add');
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        // 保存
        $result = $model->publish($_uid, $data, $cates, $tags);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return $result;
    }

    // 改变（直接修改，软删除，改变状态，排序）
    public function onEdit()
    {
        $opt    = $this->option();
        $_id    = $opt->getData('id', 0, 'intval');
        $cates  = $opt->getData("cates", [], "is_array");
        $tags   = $opt->getData("tag_ids", [], "is_array");
        $cateId = $opt->getData("cate_id", 0, "intval");
        $_uid   = $opt->getData('uid', 0, 'intval'); // 默认
        if(empty($_id)){
            return $this->_returnFail('select_operation_id');
        }
        if(empty($cateId)){
            //return $this->_returnFail('select_the_posting_cate');
        }

        // 数据
        $cates = [$cateId];
        $data  = $this->_before();
        if($data === false){
            return $this->_returnFail('add_the_saved_data');
        }
        /*if(empty($_uid)){
            return $this->_returnFail('select_the_posting_user');
        }*/

        // 整理标签
        $en_keywords = $data['en_keywords'] ?? [];
        $cn_keywords = $data['cn_keywords'] ?? [];
        if($en_keywords){
            $tags = $this->getTagsFromKeyWord($en_keywords, $cn_keywords);
            if($tags === false){
                return false;
            }
        }

        // 用于编辑的 id
        $data['id'] = $_id;
        // 验证
        $model  = new News();
        $result = $model->checkRules($data, 'edit');
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        // 保存
        $result = $model->publish($_uid, $data, $cates, $tags);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return $result;
    }

    // 评论列表

    // 列表查询
    protected function listWhere()
    {
        $option  = $this->option();
        $where   = [['news.verify', '>=', 0]];
        $bang    = [];
        $uid     = $option->getData('uid', 0, 'intval');
        $is_top  = $option->getData('is_top', null, 'intval');
        $_verify = $option->getData('verify', null, 'intval');
        $_type   = $option->getData('event_type', null, 'trim');
        $title   = $option->getData('title', null, 'trim');
        $keyword = $option->getData('keyword', null, 'trim');
        $tag_id  = $option->getData('tag_id', null, 'intval');
        $cate_id = $option->getData('cate_id', null, 'intval');
        $_header = $option->getData('is_header', null, 'intval');
        $_major  = $option->getData('is_major', null, 'intval');
        $is_user = $option->getData('is_user', null, 'intval');

        if($cate_id){
            $bang[]  = 'cate_id';
            $where[] = ['cate.cate_id', '=', $cate_id];
            $where[] = ['cate.status', '=', 1];
        }
        if($tag_id){
            $bang[]  = 'tag_id';
            $where[] = ['tag.tag_id', '=', $tag_id];
        }
        if($uid){
            $bang[]  = 'uid';
            $where[] = ['news.uid', '=', $uid];
        }
        if($is_user){
            //$bang[]  = 'uid';
            $where[] = ['news.uid', '>', 0];
        }
        if(!is_null($is_top)){
            $bang[]  = 'is_top';
            $where[] = ['news.is_top', '=', $is_top];
        }
        if(!is_null($_header)){
            $bang[]  = 'is_header';
            $where[] = ['news.is_header', '=', $_header];
        }
        if(!is_null($_major)){
            $bang[]  = 'is_major';
            $where[] = ['news.is_major', '=', $_major];
        }
        if(!is_null($_verify)){
            $bang[]  = 'verify';
            $where[] = ['news.verify', '=', $_verify];
        }
        if($title){
            $bang    = false;
            $where[] = $this->orWhere('news.en_title|news.cn_title|news.tc_title', 'like', $title);
        }
        if($keyword){
            $where[] = $this->orWhere('news.en_title|news.cn_title|news.tc_title|news.en_description|news.cn_description|news.tc_description', 'like', $keyword);
            //$where[] = $this->orWhere('news.cn_title|news.cn_description', 'like', $keyword);
            $bang = false;
        }

        // 缓存
        $this->bang = $bang;

        return $where;
    }

    // 添加 修改 前置操作
    protected function _before()
    {
        // 获取参数
        $opt  = $this->option();
        $_uid = $opt->getData('uid', 86, 'intval'); // 默认
        $data = [
            //'id' => $opt->getData("id", null, "intval"),
            //'uid'         => $_uid,
            'pic'         => $opt->getData("pic", null, "trim"),
            'ip'          => $opt->getIp(),

            // 各个语言的字段
            'en_title'    => $opt->getData("en_title", null, "trim"),
            'cn_title'    => $opt->getData("cn_title", null, "trim"),
            'tc_title'    => $opt->getData("tc_title", null, "trim"),
            'en_content'  => $opt->getData("en_content", '', "trim"),
            'cn_content'  => $opt->getData("cn_content", '', "trim"),
            'tc_content'  => $opt->getData("tc_content", '', "trim"),
            'en_keywords' => $opt->getData("en_keywords", null, "trim"),
            'cn_keywords' => $opt->getData("cn_keywords", null, "trim"),
            'tc_keywords' => $opt->getData("tc_keywords", null, "trim"),
            //'en_description' => $opt->getData("en_description", null, "trim"),
            //'cn_description' => $opt->getData("cn_description", null, "trim"),
            //'tc_description' => $opt->getData("tc_description", null, "trim"),


            // 其他
            'images'      => $opt->getData("images", '[]', "json_encode"),
            'author'      => $opt->getData("author", null, "trim"),
            'verify'      => $opt->getData("verify", 1, "intval"),
            'is_top'      => $opt->getData("is_top", null, "intval"),
            'is_header'   => $opt->getData("is_header", null, "intval"),
            'is_major'    => $opt->getData("is_major", null, "intval"),
            'push_time'   => $opt->getData("push_time", null, "intval"),
            'is_draft'    => $opt->getData("is_draft", 0, "intval"),
            //'images'      => '[]',
            //'read_no'     => $opt->getData("read_no", null, "intval"),
            //'virtual_no'  => $opt->getData("virtual_no", null, "intval"),
            //'praise_no'   => $opt->getData("praise_no", null, "intval"),
            //'collect_no'  => $opt->getData("collect_no", null, "intval"),
            //'relay_no'    => $opt->getData("relay_no", null, "intval"),
            //'comment_no'  => $opt->getData("comment_no", null, "intval"),
            //'ip_address'  => $opt->getData("ip_address", null, "trim"),
            //'ctime'       => $opt->getData("ctime", null, "intval"),
            //'mtime'       => $opt->getData("mtime", null, "intval"),
        ];

        // 图片
        // 内容中的图片
        // 多图
        // 改变图片域名地址
        $domain    = env('STYLE_HOST');
        $oldDomain = env('OLD_HOST');
        if($data['pic']){
            $data['pic'] = str_replace($domain, $oldDomain, $data['pic']);
        }
        if($data['en_content']){
            $data['en_content'] = str_replace($domain, $oldDomain, $data['en_content']);
            $data['en_content'] = html_entity_decode($data['en_content']);
            if($data['images'] = '[]'){
                $data['images'] = json_encode(getImage4content($data['en_content']));
            }
        }
        if($data['cn_content']){
            $data['cn_content'] = str_replace($domain, $oldDomain, $data['cn_content']);
            $data['cn_content'] = html_entity_decode($data['cn_content']);
        }

        // 判断
        $data = $this->filterNull($data);
        if(empty($data)){
            return $this->_returnFail('add_the_saved_data');
        }
        if($data === false){
            return $this->_returnFail('add_the_saved_data');
        }

        // 执行翻译
        /*$translate = new Translate();
        $fields    = ['title', 'description', 'content',];  // 需要翻译的字段
        $fields    = ['title', 'content',];  // 需要翻译的字段
        foreach($fields as $_field){
            $has = '';
            $no  = [];
            if(!empty($data['cn_'.$_field])){
                $has = 'cn';
            } else{
                $no[] = 'cn';
            }
            // 取消繁体翻译
            *if(!empty($data['tc_'.$_field])){
                $has = 'tc';
            } else{
                $no[] = 'tc';
            }*
            if(!empty($data['en_'.$_field])){
                $has = 'en';
            } else{
                $no[] = 'en';
            }
            if(empty($no)){
                continue;
            }
            if(empty($has)){
                continue;
            }

            // 执行翻译
            foreach($no as $_no){
                $result = $translate->translateTo($data[$has.'_'.$_field], $_no);
                // 组合翻译后的数据
                $data[$_no.'_'.$_field] = $result['text'] ?? '';
            }
        }*/


        return $data;
    }

    // 整理结果
    protected function makeNewsListsResult($list)
    {
        if(empty($list)){
            return $list;
        }

        // 返回编辑作者
        $sCateDb = new SiteCate();
        $sTagDb  = new SiteTag();
        $nCateDb = new NewsCate();
        $nTagDb  = new NewsTag();
        $nDescDb = new NewsDesc();
        $userDb  = new User();
        $uids    = array_unique(array_column($list, 'uid'));
        $users   = $userDb->isCache(true)->getListInIds($uids);  // ->isCache(true)  // 缓存要报错

        // 获取文章详情
        //   取第一段
        $domain    = env('STYLE_HOST');
        $oldDomain = env('OLD_HOST');
        $descs     = $nDescDb->isCache(true)->getListInIds(array_column($list, 'id'), '*', 'news_id');
        foreach($descs as $_key => $_desc){
            $number = 0;
            $strpos = strpos($_desc['en_content'], '<img');
            if($strpos !== false){
                $number = $strpos > 50 ? 0 : 1;  // 可能有p标签
            }

            // 截取第一段
            $en_contents = explode('</p>', $_desc['en_content']);
            $cn_contents = explode('</p>', $_desc['cn_content']);
            $tc_contents = explode('</p>', $_desc['tc_content']);

            // 重新组合 描述
            $descs[$_key]['en_description'] = strip_tags($en_contents[$number] ?? $en_contents[0]);
            $descs[$_key]['cn_description'] = strip_tags($cn_contents[$number] ?? $cn_contents[0]);
            $descs[$_key]['tc_description'] = strip_tags($tc_contents[$number] ?? $tc_contents[0]);
            $descs[$_key]['en_content']     = str_replace($oldDomain, $domain, $_desc['en_content']);
            $descs[$_key]['cn_content']     = str_replace($oldDomain, $domain, $_desc['cn_content']);
            $descs[$_key]['tc_content']     = str_replace($oldDomain, $domain, $_desc['tc_content']);
        }


        // 整理
        foreach($list as &$item){
            $_uid    = $item['uid'];
            $_newsId = $item['id'];
            $tags    = [];
            $cates   = [];
            $en_cate = '';
            $nTags   = $nTagDb->isCache(true)->getList(['news_id' => $_newsId]);
            $nCates  = $nCateDb->isCache(true)->getList(['news_id' => $_newsId]);
            if($nTags){
                $tagIds = array_column($nTags, 'tag_id');
                $tags   = $sTagDb->isCache(true)->getListInIds($tagIds);
                $tags   = array_values($tags);
            }

            if($nCates){
                $cateIds = array_column($nCates, 'cate_id');
                $cates   = $sCateDb->isCache(true)->getListInIds($cateIds);
                $cates   = array_values($cates);
                foreach($cates as $_cate){
                    $en_cate = $_cate['en_title'];
                }
            }

            // 改变图片域名地址
            if($item['pic']){
                $item['pic'] = str_replace($oldDomain, $domain, $item['pic']);
            }
            // 图片集
            $userInfo       = isset($users[$_uid]) ? $users[$_uid] : (object)[];
            $item['images'] = json_decode($item['images']);
            if($item['images']){
                $images = [];
                foreach($item['images'] as $_img){
                    $images[] = str_replace($oldDomain, $domain, $_img);
                }
                // 整理
                $item['images'] = $images;
            }

            $item['en_content'] = $descs[$_newsId]['en_content'] ?? '';
            $item['cn_content'] = $descs[$_newsId]['cn_content'] ?? '';
            $item['tc_content'] = $descs[$_newsId]['tc_content'] ?? '';
            if(!empty($descs[$_newsId]['en_description'])){
                $item['en_description'] = strip_tags($descs[$_newsId]['en_description']);
            }
            if(!empty($descs[$_newsId]['cn_description'])){
                $item['cn_description'] = strip_tags($descs[$_newsId]['cn_description']);
            }
            if(!empty($descs[$_newsId]['tc_description'])){
                $item['tc_description'] = strip_tags($descs[$_newsId]['tc_description']);
            }
            if($item['en_description']){
                $item['en_description'] = str_replace("\n", "", $item['en_description']);
            }
            if($item['cn_description']){
                $item['cn_description'] = str_replace("\n", "", $item['cn_description']);
            }
            if($item['tc_description']){
                $item['tc_description'] = str_replace("\n", "", $item['tc_description']);
            }

            // 整理
            //$item['user']    = isset($users[$_uid]) ? $users[$_uid] : [];
            //$item['user']    = $userInfo;
            $item['tags']    = $tags;
            $item['cates']   = $cates;
            $item['en_cate'] = $en_cate;

            // 头像
            /*if($item['user']){
                $item['user']['head_img'] = $this->getFullUrl($item['user']['head_img']);
            }*/
        }

        return $list;
    }

    // 整理结果
    protected function makeNewsInfoResult($info)
    {
        if(empty($info)){
            return $info;
        }

        // 改变图片域名地址
        $domain    = env('STYLE_HOST');
        $oldDomain = env('OLD_HOST');
        if($info['pic']){
            $info['pic'] = str_replace($oldDomain, $domain, $info['pic']);
        }
        if($info['tc_content']){
            $info['tc_content'] = str_replace($oldDomain, $domain, $info['tc_content']);
        }
        if($info['en_content']){
            $info['en_content'] = str_replace($oldDomain, $domain, $info['en_content']);
        }
        if($info['cn_content']){
            $info['cn_content'] = str_replace($oldDomain, $domain, $info['cn_content']);
        }

        // 图片集
        $info['images'] = json_decode($info['images']);
        if($info['images']){
            $images = [];
            foreach($info['images'] as $_img){
                $images[] = str_replace($oldDomain, $domain, $_img);
            }
            // 整理
            $info['images'] = $images;
        }

        // 整理
        $info['en_description'] = str_replace("\n", "", $info['en_description']);
        $info['cn_description'] = str_replace("\n", "", $info['cn_description']);
        $info['tc_description'] = str_replace("\n", "", $info['tc_description']);
        // 头像
        /*if($info['user']){
            $info['user']['head_img'] = $this->getFullUrl($info['user']['head_img']);
        }*/

        return $info;
    }

    // 整理标签
    protected function getTagsFromKeyWord($en_keywords, $cn_keywords)
    {
        $en_keywords = explode(',', $en_keywords);
        $cn_keywords = explode(',', $cn_keywords);
        // 判断是否已经存在标签
        if(count($en_keywords) != count($cn_keywords)){
            return $this->_returnFail('中文英文标签个数不一致！');
        }
        // 保存标签
        // 判断标签是否存在
        $tagDb = new SiteTag();
        $tags  = [];
        $time  = LARAVEL_TIME;
        foreach($en_keywords as $_kk => $en_word){
            $en_word = trim($en_word);
            $cn_word = trim($cn_keywords[$_kk]);
            // 查询标签是否存在
            $info = $tagDb->isCache(true)->oneFind(['en_title' => $en_word]);
            if(empty($info)){
                $_row = ['en_title' => $en_word, 'cn_title' => $cn_word, 'tc_title' => '', 'ctime' => $time, 'mtime' => $time,];
                $id   = (new SiteTag())->oneAdd($_row);
                // 组合
                $tags[] = $id;
            } else{
                // 组合
                $tags[] = $info['id'];
            }
        }

        return $tags;
    }

}


